home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / vsc92nov.zip / Symbol.c < prev    next >
C/C++ Source or Header  |  1992-11-02  |  4KB  |  185 lines

  1. /*
  2.  * Symbol.c -- Implementation of Scheme Symbols
  3.  *
  4.  * (C) m.b (Matthias Blume), Mar 1992, HUB/Ger
  5.  */
  6.  
  7. # ident "@(#)Symbol.c    (C) M.Blume, Humboldt-Uni Berlin, 1.2"
  8.  
  9. # include <stdio.h>
  10. # include <string.h>
  11. # include <ctype.h>
  12.  
  13. # include "storext.h"
  14. # include "Symbol.h"
  15. # include "Primitive.h"
  16. # include "identifier.h"
  17. # include "type.h"
  18. # include "except.h"
  19.  
  20. # define SPECIAL_CHARS " \t\n\r\b\a\v\\\"\',@()."
  21.  
  22. # define SYMTAB_HASH_SIZE 41
  23.  
  24. static
  25. ScmSymbol *symbol_table [SYMTAB_HASH_SIZE];
  26.  
  27. static
  28. size_t size_hook (void *vsym)
  29. {
  30.   return (sizeof (ScmSymbol) + ((ScmSymbol *)vsym)->length - 1);
  31. }
  32.  
  33. static
  34. void apply_to_subs (void *vsym, applied_proc proc, void *cd)
  35. {
  36.   ScmSymbol *sym = (ScmSymbol *) vsym;
  37.  
  38.   (*proc) ((void *)&sym->hashlink, cd);
  39.   (*proc) ((void *)&sym->value, cd);
  40.   (*proc) ((void *)&sym->properties, cd);
  41. }
  42.  
  43. static
  44. void dump (void *vsym, FILE *file)
  45. {
  46.   ScmSymbol *sym = (ScmSymbol *) vsym;
  47.   unsigned i;
  48.  
  49.   dump_ul (sym->length, file);
  50.   for (i = 0; i < sym->length; i++)
  51.     putc (sym->array[i], file);
  52. }
  53.  
  54. static
  55. void *restore_init (FILE *file)
  56. {
  57.   ScmSymbol *sym;
  58.   unsigned i;
  59.   unsigned short length;
  60.  
  61.   length = restore_ul (file);
  62.   sym = getmem (ScmType (Symbol), sizeof (ScmSymbol) + length - 1);
  63.   sym->length = length;
  64.   for (i = 0; i < length; i++)
  65.     if ((sym->array[i] = getc (file)) == EOF)
  66.       fatal ("bad dump file format (Symbol)");
  67.   return sym;
  68. }
  69.  
  70. static
  71. void display (void *vsym, putc_proc pp, void *cd)
  72. {
  73.   ScmSymbol *sym = vsym;
  74.   unsigned i;
  75.  
  76.   for (i = 0; i < sym->length; i++)
  77.     (* pp) (sym->array[i], cd);
  78. }
  79.  
  80. static
  81. void write_this (void *vsym, putc_proc pp, void *cd)
  82. {
  83.   ScmSymbol *sym = vsym;
  84.   unsigned i;
  85.   int c;
  86.  
  87.   for (i = 0; i < sym->length; i++) {
  88.     c = sym->array[i];
  89.     if (strchr (SPECIAL_CHARS, c) == NULL)
  90.       if (isprint (c))
  91.     (* pp) (c, cd);
  92.       else {
  93.     char buf[16];
  94.     sprintf (buf, "\\%03o", (unsigned char)c);
  95.     putc_string (buf, pp, cd);
  96.       }
  97.     else {
  98.       (* pp) ('\\', cd);
  99.       (* pp) (c, cd);
  100.     }
  101.   }
  102. }
  103.  
  104. static
  105. void apply_to_symtab_entries (void *vsymtab, applied_proc proc, void *cd)
  106. {
  107.   int i;
  108.   ScmSymbol **symtab = vsymtab;
  109.  
  110.   for (i = 0; i < SYMTAB_HASH_SIZE; i++)
  111.     (* proc) ((void *)&symtab[i], cd);
  112. }
  113.  
  114. static
  115. int hash_key (const char *string, unsigned short length)
  116. /* string is not necessarily a C-string (0-terminated), so we need its length */
  117. {
  118.   int sum;
  119.  
  120.   sum = 0;
  121.   while (length--)
  122.     sum += (unsigned char) *string++;
  123.   return sum % SYMTAB_HASH_SIZE;
  124. }
  125.  
  126. void *ScmMakeSymbol (const char *name, unsigned short length)
  127. /* name is not necessarily a C-string (0-terminated), so we need its length */
  128. {
  129.   int key = hash_key (name, length);
  130.   ScmSymbol *l = symbol_table [key];
  131.  
  132.   while (l != NULL) {
  133.     if (length == l->length && memcmp (name, l->array, length) == 0)
  134.       break;
  135.     l = l->hashlink;
  136.   }
  137.  
  138.   if (l == NULL) {
  139.     l = getmem (ScmType (Symbol), sizeof (ScmSymbol) + length - 1);
  140.     l->hashlink = symbol_table [key];
  141.     symbol_table [key] = l;
  142.     l->value = l->properties = NULL;
  143.     l->length = length;
  144.     memcpy (l->array, name, length);
  145.   }
  146.   return l;
  147. }
  148.  
  149. void ScmInitSymtab (void)
  150. {
  151.   int i;
  152.   unsigned long seq_num;
  153.   ScmPrimitive *prim;
  154.   ScmSymbol *sym;
  155.  
  156.   /* Make an empty hash table */
  157.   for (i = 0; i < SYMTAB_HASH_SIZE; i++)
  158.     symbol_table [i] = NULL;
  159.  
  160.   /* register symbol_table at storage module */
  161.   register_global_object (symbol_table, apply_to_symtab_entries);
  162.  
  163.   for (seq_num = 0; (prim = GetScmPrimitive (seq_num)) != NULL; seq_num++) {
  164.     sym = ScmMakeSymbol (prim->name, strlen (prim->name));
  165.     sym->value = prim;
  166.   }
  167. }
  168.  
  169. static
  170. struct scheme_od_extension ext = {
  171.   display, write_this,
  172.   NULL, NULL,        /* Symbols must coincide to be equal */
  173. };
  174.  
  175. OD_VECTOR (ScmSymbol_od_vector,
  176.   0,
  177.   size_hook,
  178.   apply_to_subs,
  179.   SYMBOL_IDENTIFIER,
  180.   dump, restore_init, NULL,
  181.   NULL,
  182.   NULL, NULL,
  183.   &ext
  184. );
  185.